
import os
import sys

import rpyc
from rpyc.utils import server
from rpyc.utils.factory import DiscoveryError

import dexen
from dexen.system import util
from dexen.system.constants import NS_NAME

#===============================================================================
# Service Class
#===============================================================================
class SlaveService(dexen.Service):
    def on_connect(self):
        super(SlaveService, self).on_connect()
        self.objs = {}
    
    def on_disconnect(self):
        super(SlaveService, self).on_disconnect()   
         
    def _get_task_obj(self, schema_name, task_name):
        try:
            task = self.tasks_info[task_name]
            if task_name in self.objs.keys():
                return self.objs[task_name]
            prev_dir = os.getcwd()
            os.chdir(os.path.join(prev_dir, slave_name, schema_name)) 
            module = __import__(task["file_name"], fromlist=[""])
            classobj = getattr(module, task["class_name"])
            obj = classobj()
            obj.__initialize__()
            self.objs[task_name] = obj
            os.chdir(prev_dir)
        except:
            import traceback
            traceback.print_tb(sys.exc_info()[2])
            print sys.exc_info()[1]
        return obj

    def setup_schema(self, schema_zip, schema_name, tasks_info):
        util.unzip(schema_zip, os.path.join(slave_name, schema_name))
        sys.path.append(os.path.join(os.getcwd(), slave_name, schema_name))
        self.schema_name = schema_name
        self.tasks_info = rpyc.classic.obtain(tasks_info)
        
    def execute_task(self, task_name, input):
        print "in execute task", task_name, len(input)
        input = rpyc.classic.obtain(input)
        obj = self._get_task_obj(self.schema_name, task_name)
        res = obj.__execute__(input)
        return res
    
    def get_attributes(self):
        print "I am in get attributes"
        return None
    
#===============================================================================
# MAIN
#===============================================================================
def main():
    global slave_name
    try:
        conn = rpyc.connect_by_service(service_name=NS_NAME,
                config={"allow_pickle":True, "allow_all_attrs":True})
        slave_name, = conn.root.register_slave()
        if os.path.exists(slave_name):
            util.del_tree(slave_name)
        else:
            os.mkdir(slave_name)
        SlaveService.ALIASES = [slave_name]     
        svr = server.ThreadedServer(SlaveService, auto_register=True,
                protocol_config={"allow_pickle":True,
                                 "instantiate_custom_exceptions":True})
        svr.start()
    except DiscoveryError:
        print "Discovery Error: Naming Server '%s' couldn't be found." %NS_NAME

if __name__ == '__main__':
    main()
    

